#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
int flag = 0;//修改密码用，做标记。
struct student{
    int id, sex, score[10], collage;
	char name[32], sexno[3], collageno[32];
	double ave;
}S[100], temp;//所有数据。sex是性别代号，sexno是性别代号对应的中文。collage是学院代号，collageno是。。。

struct col{
	char collage1[32];
	int n;
}S1[10];//取文件里面的学院。

struct Sex {
	int m;
	char sex1[5];
}S2[2];//取文件里面的性别。

void read(char *file1, char *file2, char *file3, student S[100], col S1[10]) {
	FILE *fp1, *fp2, *fp3;//定义文件指针
	int i, j;
	fp1 = fopen(file1, "r");//打开文件下同。
	fp2 = fopen(file2, "r");
	fp3 = fopen(file3, "r");
	double sum, ave;
	fscanf(fp3, "%d%s", &S2[0].m, S2[0].sex1);//从文件取出数据给结构体，后面的fscanf都一样。
	fscanf(fp3, "%d%s", &S2[1].m, S2[1].sex1);
	for(i = 0; i < 100; i++) {//有很多个学生，只是学生数量
		sum = 0;
		fscanf(fp1, "%d%s%d%d", &S[i].id, S[i].name, &S[i].sex, &S[i].collage);//只是学生数量的前几个数值，一次取文件一个数值，相对应，遇空格结束。
		for(j = 0; j < 10; j++) {//取10个成绩数据。
			fscanf(fp1, "%d", &S[i].score[j]);
			sum += S[i].score[j];
		}
		S[i].ave = sum / 10.0;//平均数
	}
	for(i = 0; i < 10; i++) {//取学院的代号和名字给这个结构体
		fscanf(fp2, "%d%s", &S1[i].n, S1[i].collage1);
	}
	for(i = 0; i < 100; i++) {//对性别和学院代号的改变。细心应该看得懂。
		if(S[i].sex == S2[0].m)
			strcpy(S[i].sexno, S2[0].sex1);
		else strcpy(S[i].sexno, S2[1].sex1);
		for(j = 0; j < 10; j++) {
			if(S[i].collage == S1[j].n - 1)
				strcpy(S[i].collageno, S1[j].collage1);
		}
	}
	fclose(fp1);//关闭文件。
	fclose(fp2);
	fclose(fp3);
}

void rankave(student S[100]) {//平均成绩降序排序.
	int i, j;
	for(i = 0; i  < 100; i++) {//排序.
		for(j = 1; j < 100 - i; j++) {
			if(S[j].ave > S[j-1].ave) {
				temp = S[j];
				S[j] = S[j-1];
				S[j-1] = temp;
			}
		}
	}
	for(i = 0; i < 100; i++) {//输出.
		printf("%d %s %s %11s ", S[i].id, S[i].name, S[i].sexno, S[i].collageno);
		for(j = 0; j < 10; j++) {
			printf("%3d ", S[i].score[j]);
		}
		printf("%5.2lf\n", S[i].ave);
	}
}

void rankname(student S[100]) {//姓名升序排序。和上面一样。。。
	int i, j;
	for(i = 0; i  < 100; i++) {
		for(j = 1; j < 100 - i; j++) {
			if(strcmp(S[j].name, S[j-1].name) > 0) {
				temp = S[j];
				S[j] = S[j-1];
				S[j-1] = temp;
			}
		}
	}
	for(i = 0; i < 100; i++) {
		printf("%d %s %s %11s ", S[i].id, S[i].name, S[i].sexno, S[i].collageno);
		for(j = 0; j < 10; j++) {
			printf("%3d ", S[i].score[j]);
		}
		printf("%5.2lf\n", S[i].ave);
	}
}

void seeid(student S[100]) {//学号查询.就是对照是就输出，应要求，得可以重复查询。
	int a, i, j, ch;
	while(1) {
		printf("请输入要查询的学号：");
		scanf("%d", &a);
		for(i = 0; i < 100; i++) {
			if(a == S[i].id) {
				printf("%d %s %s %11s ", S[i].id, S[i].name, S[i].sexno, S[i].collageno);
				for(j = 0; j < 10; j++) {
					printf("%3d ", S[i].score[j]);
				}
				printf("%5.2lf\n", S[i].ave);
			}
		}
		printf("输入-1返回主菜单,按任意数字继续查询:");
		scanf("%d", &ch);
		if(ch == -1)
			return ;
	}
}

void seename(student S[100]) {////姓名查询.就是对照是就输出，应要求，得可以重复查询。一样拉。
	int i, j, ch;
	char a[32];
	while(1) {
		printf("请输入要查询学生的名字:");
		scanf("%s" , a);
		for(i = 0; i < 100; i++) {
			if(strcmp(a, S[i].name) == 0) {
				printf("%d %s %s %11s ", S[i].id, S[i].name, S[i].sexno, S[i].collageno);
				for(j = 0; j < 10; j++) {
					printf("%3d ", S[i].score[j]);
				}
				printf("%5.2lf\n", S[i].ave);
				break;
			}
		}
		printf("输入-1返回主菜单,按任意数字继续查询:");
		scanf("%d", &ch);
		if(ch == -1)
			return ;
	}
}

void stacollage(student S[100]) {//学院学生查询。还是差不多。。。
	int i, j, a;
	printf("请输入学院代号:");
	scanf("%d" , &a);
	for(i = 0; i < 100; i++) {
		if(a == S[i].collage) {
			printf("%d %s %s %11s  ", S[i].id, S[i].name, S[i].sexno, S[i].collageno);
			for(j = 0; j < 10; j++) {
				printf("%3d ", S[i].score[j]);
			}
			printf("%5.2lf\n", S[i].ave);
		}
	}
}

void xinghao(int a) {//平均成绩统计。不多说，做过的。。。
	int i;
	for(i = 0; i < a; i++) 
		printf("*");
	printf("\n");
}
void sta(student S[100]) {
	int i, t = 0, r = 0, e = 0, w = 0, q = 0, a = 0;
	for(i = 0; i < 100 ; i++) {
		a = S[i].ave / 10;
		switch(a) {
		case 10:
		case 9: q++; break;
		case 8: w++; break;
		case 7: e++; break;
		case 6: r++; break;
		default: t++; break;
		}
	}
	printf("分数断          学生人数        图形\n");
	printf("<60             %d(%.2lf%%)     ", t, t / 10 * 100.0); xinghao(t);
	printf("60-69           %d(%.2lf%%)        ", r, r / 10 * 100.0); xinghao(r);
	printf("70-79           %d(%.2lf%%)     ", e, e / 10 * 100.0); xinghao(e);
	printf("80-89           %d(%.2lf%%)     ", w, w / 10 * 100.0); xinghao(w);
	printf(">=90            %d(%.2lf%%)        ", q, q / 10 * 100.0); xinghao(q);
}

char change(char ch[]) {//修改密码系统
	char ch1[32] = {0}, ch2[32] = {0};
	int a;
	printf("请输入新密码（密码为6-9个数字或字母组成的）:");
	scanf("%s", ch1);
	a = strlen(ch1);
	while(a < 6 || a > 9) {
		printf("输入的位数错误，请重新输入：");
		scanf("%s", ch1);
		a = strlen(ch1);
	}
	ch1[a] = '\r';
	printf("请再输入一遍：");
	scanf("%s", ch2);
	a = strlen(ch2);
	ch2[a] = '\r';
	while(strcmp(ch1, ch2)) {
		printf("2次密码不同,请重新输入：");
		scanf("%s", ch2);
		a = strlen(ch2);
		ch2[a] = '\r';
	}
	strcpy(ch, ch1);//改变密码
	flag = 2;//标记。
	printf("修改成功\n");
	return ch[32];
}

int main() {
	int sele, i, a;
	char ch[32] = {'m', 'i', 'm', 'a', '0', '0', '7', '\r'}, ch1[32] = {0};	
	read("C:\\Users\\Administrator\\Desktop\\StudentInfo.txt", "C:\\Users\\Administrator\\Desktop\\CodeInfo.txt", "C:\\Users\\Administrator\\Desktop\\SexInfo.txt", S, S1);//读取文件。
	while(1) {//做菜单，无限循环。
		if(flag == 0 || flag == 2) {//输入密码，判断，只有第一次和修改密码了才需要输入密码。
			if(flag == 2) {//修改密码的情况
				system("cls");
				printf("密码已被修改要访问请重新输入新密码：");
				a = 0;
				for(i = 0; i < 32; i++) {
					a++;
					if(ch[i] == '\r') break;
				}
				for(i = 0; i < a; i++) {
					ch1[i] = getch();
					printf("*");
				}
			}
			a = strlen(ch);
			if(flag == 0) { //一般第一次进入的情况。
				printf("要访问请输入密码(初始密码为：mima007)：");
				for(i = 0; i < a; i++) {
					ch1[i] = getch();
					printf("*");
				}
			}
			while(strcmp(ch, ch1) != 0) {//错误的情况
				printf("\n密码错误请重新输入:");
				for(i = 0; i < a; i++) {
					ch1[i] = getch();
					printf("*");
				}
			}
			flag = 1;//标记，输过就不用再输了。
		}
		system("cls");//清屏，每一次都清屏。下面是菜单。
		printf("                    #######################\n");
		printf("                    #1. 平均成绩降序排序。#\n");
		printf("                    #2. 姓名升序排序。    #\n");
		printf("                    #3. 学号查询          #\n");
		printf("                    #4. 姓名查询          #\n");
		printf("                    #5. 学院学生查询      #\n");
		printf("                    #6. 平均成绩统计      #\n");
		printf("                    #7. 修改密码          #\n");
		printf("                    #8. 退出              #\n");
		printf("                    #######################\n");
		printf("                            请输入1-8:");
		scanf("%d", &sele);
		switch(sele) {//菜单的功能，也就是对应的虽有函数。
			case 1: rankave(S); break;
			case 2: rankname(S); break;
			case 3: seeid(S); break;
			case 4: seename(S); break;
			case 5: stacollage(S); break;
			case 6: sta(S); break;
			case 7: change(ch); break;
			case 8: exit(0);
			default: printf("error\n");
		}
		system("pause");//暂停，因为有个清屏，不然输出立即就清屏，什么东西都没有了。
	}
	return 0;
}
